#include "ThreadPool.h"
#include <sys/syscall.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include "Log.h"

ThreadPool::ThreadPool(int thread_num,const std::string& thread_type):m_stop(false),m_thread_type(thread_type)
{
    for(int i=0;i<thread_num;i++)
    {
        m_threads.emplace_back([this]
        {
            // 显示线程类型和线程ID。
            LOG(INFO) << "create "<<m_thread_type<<" thread("<<syscall(SYS_gettid)<<").";
            while(true)
            {
                std::function<void()> task;
                
                {
                    std::unique_lock<std::mutex> lock(this->m_mutex);
                    this->m_condition_variable.wait(lock,[this]
                    {
                        return ((this->m_stop) || (!this->m_queue.empty()));
                    });

                    if(this->m_stop && this->m_queue.empty())
                        return;

                    task=std::move(this->m_queue.front());
                    this->m_queue.pop();
                }
                
                //LOG(INFO)<<m_thread_type<<"("<<syscall(SYS_gettid)<<")"<<" execute task.";
                task();
            }
        });
    }
}

void ThreadPool::add_task(std::function<void()> fn)
{
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        
        m_queue.push(fn);
    }
    m_condition_variable.notify_one();
}

size_t ThreadPool::size()
{
    return m_threads.size();
}

void ThreadPool::stop()
{
    if(m_stop)
        return;

    m_stop=true;

    m_condition_variable.notify_all();

    for(auto& th:m_threads)
    {
        th.join();
    }
}

ThreadPool::~ThreadPool()
{
    stop();
}
